home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_arange.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.2 KB  |  495 lines

  1. #include <stdio.h>
  2. #include "dwarf_incl.h"
  3. #include "dwarf_arange.h"
  4.  
  5.  
  6. /*
  7.     This function returns the count of the number of
  8.     aranges in the .debug_aranges section.  It sets
  9.     aranges to point to a block of Dwarf_Arange's 
  10.     describing the arange's.  It returns DW_DLV_ERROR
  11.     on error.
  12.  
  13.     Must be identical in most aspects to
  14.     dwarf_get_aranges_addr_offsets!
  15. */
  16. int
  17. dwarf_get_aranges (
  18.     Dwarf_Debug        dbg,
  19.     Dwarf_Arange    **aranges,
  20.     Dwarf_Signed       *returned_count,
  21.     Dwarf_Error        *error
  22. )
  23. {
  24.     /* Sweeps the .debug_aranges section. */
  25.     Dwarf_Small        *arange_ptr;
  26.  
  27.     /* 
  28.         Start of arange header.  Used for rounding offset of
  29.         arange_ptr to twice the tuple size.  Libdwarf requirement.
  30.     */
  31.     Dwarf_Small        *header_ptr;
  32.  
  33.     /* Length of current set of aranges. */
  34.     Dwarf_Unsigned    length;
  35.  
  36.     /* Version of .debug_aranges header. */
  37.     Dwarf_Half        version;
  38.  
  39.         /* Offset of current set of aranges into .debug_info. */
  40.     Dwarf_Off            info_offset;
  41.  
  42.     /* Size in bytes of addresses in target. */
  43.     Dwarf_Small        address_size;
  44.  
  45.     /* Size in bytes of segment offsets in target. */
  46.     Dwarf_Small        segment_size;
  47.  
  48.     Dwarf_Small        remainder;
  49.  
  50.     /* Count of total number of aranges. */
  51.     Dwarf_Unsigned    arange_count = 0;
  52.  
  53.     /* Start address of arange. */
  54.     Dwarf_Addr        range_address;
  55.  
  56.     /* Length of arange. */
  57.     Dwarf_Unsigned    range_length;
  58.  
  59.     Dwarf_Arange    arange, *arange_block;
  60.  
  61.     Dwarf_Unsigned    i;
  62.  
  63.     /* Used to chain Dwarf_Aranges structs. */
  64.     Dwarf_Chain        curr_chain, prev_chain, head_chain = NULL;
  65.  
  66.     /* ***** BEGIN CODE ***** */
  67.  
  68.     if (dbg == NULL)
  69.     {_dwarf_error(NULL, error, DW_DLE_DBG_NULL); return(DW_DLV_ERROR);}
  70.  
  71.     if (dbg->de_debug_aranges == NULL) {
  72.     return(DW_DLV_NO_ENTRY);
  73.     }
  74.  
  75.     arange_ptr = dbg->de_debug_aranges;
  76.     do {
  77.     header_ptr = arange_ptr;
  78.  
  79.         /* Length of aranges for this compilation-unit. */
  80.     READ_UNALIGNED(length, arange_ptr, dbg->de_length_size);
  81.     arange_ptr += dbg->de_length_size;
  82.  
  83.     READ_UNALIGNED(version, arange_ptr, sizeof(Dwarf_Half));
  84.     arange_ptr += sizeof(Dwarf_Half);
  85.     length = length - sizeof(Dwarf_Half);
  86.     if (version != CURRENT_VERSION_STAMP) {
  87.         _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
  88.         return(DW_DLV_ERROR);
  89.     }
  90.  
  91.     READ_UNALIGNED(info_offset, arange_ptr, dbg->de_length_size);
  92.     arange_ptr += dbg->de_length_size;
  93.     length = length - dbg->de_length_size;
  94.     if (info_offset >= dbg->de_debug_info_size) {
  95.         _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
  96.         return(DW_DLV_ERROR);
  97.     }
  98.  
  99.         address_size = *(Dwarf_Small *)arange_ptr;
  100.     arange_ptr = arange_ptr + sizeof(Dwarf_Small);
  101.     length = length - sizeof(Dwarf_Small);
  102.  
  103.     segment_size = *(Dwarf_Small *)arange_ptr;
  104.     arange_ptr = arange_ptr + sizeof(Dwarf_Small);
  105.     length = length - sizeof(Dwarf_Small);
  106.     if (segment_size != 0) {
  107.         _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
  108.         return(DW_DLV_ERROR);
  109.     }
  110.  
  111.         /* Round arange_ptr offset to next multiple of address_size. */
  112.         remainder = (Dwarf_Unsigned)(arange_ptr-header_ptr) % 
  113.         (2 * address_size);
  114.     if (remainder != 0) {
  115.         arange_ptr = arange_ptr + (2*address_size) - remainder;
  116.         length = length - ((2*address_size) - remainder);
  117.     }
  118.  
  119.     do {
  120.         READ_UNALIGNED(range_address, arange_ptr, dbg->de_length_size);
  121.         arange_ptr += dbg->de_length_size;
  122.             length = length - dbg->de_length_size;
  123.  
  124.         READ_UNALIGNED(range_length, arange_ptr, dbg->de_length_size);
  125.         arange_ptr += dbg->de_length_size;
  126.             length = length - dbg->de_length_size;
  127.  
  128.         if (range_address != 0 || range_length != 0) {
  129.  
  130.             arange = (Dwarf_Arange)
  131.             _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
  132.             if (arange == NULL) {
  133.             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  134.             return(DW_DLV_ERROR);
  135.             }
  136.  
  137.         arange->ar_address = range_address;
  138.         arange->ar_length = range_length;
  139.         arange->ar_info_offset = info_offset;
  140.         arange->ar_dbg = dbg;
  141.         arange_count++;
  142.  
  143.         curr_chain = (Dwarf_Chain)
  144.             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  145.         if (curr_chain == NULL) {
  146.             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  147.             return(DW_DLV_ERROR);
  148.         }
  149.  
  150.         curr_chain->ch_item = arange;
  151.         if (head_chain == NULL) 
  152.             head_chain = prev_chain = curr_chain;
  153.         else {
  154.             prev_chain->ch_next = curr_chain;
  155.             prev_chain = curr_chain;
  156.         }
  157.         }
  158.     } while (range_address != 0 || range_length != 0);
  159.  
  160.     if (length != 0) {
  161.         _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD);
  162.         return(DW_DLV_ERROR);
  163.     }
  164.  
  165.     } while (arange_ptr < dbg->de_debug_aranges + dbg->de_debug_aranges_size);
  166.  
  167.     if (arange_ptr != dbg->de_debug_aranges + dbg->de_debug_aranges_size) {
  168.     _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
  169.     return(DW_DLV_ERROR);
  170.     }
  171.  
  172.     arange_block = (Dwarf_Arange *)
  173.     _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
  174.     if (arange_block == NULL) {
  175.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  176.     return(DW_DLV_ERROR);
  177.     }
  178.  
  179.     curr_chain = head_chain;
  180.     for (i = 0; i < arange_count; i++) {
  181.     *(arange_block + i) = curr_chain->ch_item;
  182.     prev_chain = curr_chain;
  183.     curr_chain = curr_chain->ch_next;
  184.     dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
  185.     }
  186.  
  187.     *aranges = arange_block;
  188.     *returned_count = (arange_count);
  189.     return DW_DLV_OK;
  190. }
  191.  
  192. /*
  193.     This function returns DW_DLV_OK if it succeeds
  194.     and DW_DLV_ERR or DW_DLV_OK otherwise.
  195.     count is set to the number of addresses in the
  196.     .debug_aranges section. 
  197.     For each address, the corresponding element in
  198.     an array is set to the address itself(aranges) and
  199.     the section offset (offsets).
  200.     Must be identical in most aspects to
  201.     dwarf_get_aranges!
  202. */
  203. int
  204. _dwarf_get_aranges_addr_offsets(
  205.     Dwarf_Debug        dbg,
  206.     Dwarf_Addr            **addrs,
  207.     Dwarf_Off           **offsets,
  208.     Dwarf_Signed        *count,
  209.     Dwarf_Error        *error
  210. )
  211. {
  212.     /* Sweeps the .debug_aranges section. */
  213.     Dwarf_Small        *arange_ptr;
  214.     Dwarf_Small        *arange_start_ptr;
  215.  
  216.     /* 
  217.         Start of arange header.  Used for rounding offset of
  218.         arange_ptr to twice the tuple size.  Libdwarf requirement.
  219.     */
  220.     Dwarf_Small        *header_ptr;
  221.  
  222.     /* Length of current set of aranges. */
  223.     Dwarf_Unsigned    length;
  224.  
  225.     /* Version of .debug_aranges header. */
  226.     Dwarf_Half        version;
  227.  
  228.         /* Offset of current set of aranges into .debug_info. */
  229.     Dwarf_Off            info_offset;
  230.  
  231.     /* Size in bytes of addresses in target. */
  232.     Dwarf_Small        address_size;
  233.  
  234.     /* Size in bytes of segment offsets in target. */
  235.     Dwarf_Small        segment_size;
  236.  
  237.     Dwarf_Small        remainder;
  238.  
  239.     /* Count of total number of aranges. */
  240.     Dwarf_Unsigned    arange_count = 0;
  241.  
  242.     /* Start address of arange. */
  243.     Dwarf_Addr        range_address;
  244.  
  245.     /* Length of arange. */
  246.     Dwarf_Unsigned    range_length;
  247.  
  248.     Dwarf_Arange    arange, *arange_block;
  249.  
  250.     Dwarf_Unsigned    i;
  251.  
  252.     /* Used to chain Dwarf_Aranges structs. */
  253.     Dwarf_Chain        curr_chain, prev_chain, head_chain = NULL;
  254.  
  255.     Dwarf_Addr * arange_addrs;
  256.     Dwarf_Off  * arange_offsets;
  257.  
  258.     /* ***** BEGIN CODE ***** */
  259.  
  260.     if (error != NULL) *error = NULL;
  261.  
  262.     if (dbg == NULL)
  263.     {_dwarf_error(NULL, error, DW_DLE_DBG_NULL); return(DW_DLV_ERROR);}
  264.  
  265.     if (dbg->de_debug_aranges == NULL) {
  266.     return(DW_DLV_NO_ENTRY);
  267.     }
  268.  
  269.     arange_ptr = dbg->de_debug_aranges;
  270.     do {
  271.     header_ptr = arange_ptr;
  272.  
  273.         /* Length of aranges for this compilation-unit. */
  274.     READ_UNALIGNED(length, arange_ptr, dbg->de_length_size);
  275.     arange_ptr += dbg->de_length_size;
  276.  
  277.     READ_UNALIGNED(version, arange_ptr, sizeof(Dwarf_Half));
  278.     arange_ptr += sizeof(Dwarf_Half);
  279.     length = length - sizeof(Dwarf_Half);
  280.     if (version != CURRENT_VERSION_STAMP) {
  281.         _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
  282.         return(DW_DLV_ERROR);
  283.     }
  284.  
  285.     READ_UNALIGNED(info_offset, arange_ptr, dbg->de_length_size);
  286.     arange_ptr += dbg->de_length_size;
  287.     length = length - dbg->de_length_size;
  288.     if (info_offset >= dbg->de_debug_info_size) {
  289.         _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
  290.         return(DW_DLV_ERROR);
  291.     }
  292.  
  293.         address_size = *(Dwarf_Small *)arange_ptr;
  294.     arange_ptr = arange_ptr + sizeof(Dwarf_Small);
  295.     length = length - sizeof(Dwarf_Small);
  296.  
  297.     segment_size = *(Dwarf_Small *)arange_ptr;
  298.     arange_ptr = arange_ptr + sizeof(Dwarf_Small);
  299.     length = length - sizeof(Dwarf_Small);
  300.     if (segment_size != 0) {
  301.         _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
  302.         return(DW_DLV_ERROR);
  303.     }
  304.  
  305.         /* Round arange_ptr offset to next multiple of address_size. */
  306.         remainder = (Dwarf_Unsigned)(arange_ptr-header_ptr) % 
  307.         (2 * address_size);
  308.     if (remainder != 0) {
  309.         arange_ptr = arange_ptr + (2*address_size) - remainder;
  310.         length = length - ((2*address_size) - remainder);
  311.     }
  312.  
  313.     do {
  314.         arange_start_ptr = arange_ptr;
  315.         READ_UNALIGNED(range_address, arange_ptr, dbg->de_length_size);
  316.         arange_ptr += dbg->de_length_size;
  317.             length = length - dbg->de_length_size;
  318.  
  319.         READ_UNALIGNED(range_length, arange_ptr, dbg->de_length_size);
  320.         arange_ptr += dbg->de_length_size;
  321.             length = length - dbg->de_length_size;
  322.  
  323.         if (range_address != 0 || range_length != 0) {
  324.  
  325.             arange = (Dwarf_Arange)
  326.             _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
  327.             if (arange == NULL) {
  328.             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 
  329.             return(DW_DLV_ERROR);
  330.             }
  331.  
  332.         arange->ar_address = range_address;
  333.         arange->ar_length = range_length;
  334.         arange->ar_info_offset = arange_start_ptr - dbg->de_debug_aranges;
  335.         arange->ar_dbg = dbg;
  336.         arange_count++;
  337.  
  338.         curr_chain = (Dwarf_Chain)
  339.             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  340.         if (curr_chain == NULL) {
  341.             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  342.             return(DW_DLV_ERROR);
  343.         }
  344.  
  345.         curr_chain->ch_item = arange;
  346.         if (head_chain == NULL) 
  347.             head_chain = prev_chain = curr_chain;
  348.         else {
  349.             prev_chain->ch_next = curr_chain;
  350.             prev_chain = curr_chain;
  351.         }
  352.         }
  353.     } while (range_address != 0 || range_length != 0);
  354.  
  355.     if (length != 0) {
  356.         _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD);
  357.         return(DW_DLV_ERROR);
  358.     }
  359.  
  360.     } while (arange_ptr < dbg->de_debug_aranges + dbg->de_debug_aranges_size);
  361.  
  362.     if (arange_ptr != dbg->de_debug_aranges + dbg->de_debug_aranges_size) {
  363.     _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
  364.     return(DW_DLV_ERROR);
  365.     }
  366.  
  367.     arange_addrs = (Dwarf_Addr *)
  368.     _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
  369.     if (arange_addrs == NULL) {
  370.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  371.     return(DW_DLV_ERROR);
  372.     }
  373.     arange_offsets = (Dwarf_Off *)
  374.     _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
  375.     if (arange_offsets == NULL) {
  376.     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  377.     return(DW_DLV_ERROR);
  378.     }
  379.  
  380.     curr_chain = head_chain;
  381.     for (i = 0; i < arange_count; i++) {
  382.     Dwarf_Arange   ar = curr_chain->ch_item;
  383.     arange_addrs[i] = ar->ar_address;
  384.     arange_offsets[i] = ar->ar_info_offset;
  385.     prev_chain = curr_chain;
  386.     curr_chain = curr_chain->ch_next;
  387.     dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
  388.     dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
  389.     }
  390.     *count = arange_count;
  391.     *offsets = arange_offsets;
  392.     *addrs = arange_addrs;
  393.     return(DW_DLV_OK);
  394. }
  395.  
  396.  
  397. /*
  398.     This function takes a pointer to a block
  399.     of Dwarf_Arange's, and a count of the
  400.     length of the block.  It checks if the
  401.     given address is within the range of an
  402.     address range in the block.  If yes, it
  403.     returns the appropriate Dwarf_Arange.
  404.     Otherwise, it returns DW_DLV_ERROR.
  405. */
  406. int
  407. dwarf_get_arange (
  408.     Dwarf_Arange    *aranges,
  409.     Dwarf_Unsigned    arange_count,
  410.     Dwarf_Addr            address,
  411.     Dwarf_Arange       *returned_arange,
  412.     Dwarf_Error        *error
  413. )
  414. {
  415.     Dwarf_Arange    curr_arange;
  416.     Dwarf_Unsigned    i;
  417.  
  418.     if (aranges == NULL) {
  419.     _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
  420.     return(DW_DLV_ERROR);
  421.     }
  422.  
  423.     for (i = 0; i < arange_count; i++) {
  424.     curr_arange = *(aranges + i);
  425.     if (address >= curr_arange->ar_address &&
  426.         address < curr_arange->ar_address + curr_arange->ar_length) {
  427.         *returned_arange = curr_arange;
  428.             return(DW_DLV_OK);
  429.         }
  430.     }
  431.  
  432.     return(DW_DLV_NO_ENTRY);
  433. }
  434.  
  435.  
  436. /*
  437.     This function takes an Dwarf_Arange,
  438.     and returns the offset of the first
  439.     die in the compilation-unit that the
  440.     arange belongs to.  Returns DW_DLV_ERROR
  441.     on error.
  442. */
  443. int
  444. dwarf_get_cu_die_offset (
  445.     Dwarf_Arange    arange,
  446.     Dwarf_Off      *    returned_offset,
  447.     Dwarf_Error        *error
  448. )
  449. {
  450.     if (arange == NULL) {
  451.     _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 
  452.     return(DW_DLV_ERROR);
  453.     }
  454.  
  455.     *returned_offset =
  456.     (arange->ar_info_offset + arange->ar_dbg->de_length_size + 
  457.     CU_VERSION_STAMP_SIZE + arange->ar_dbg->de_length_size + 
  458.     CU_ADDRESS_SIZE_SIZE);
  459.     return DW_DLV_OK;
  460. }
  461.  
  462.  
  463. /*
  464.     This function takes a Dwarf_Arange, and returns
  465.     true if it is not NULL.  It also stores the start
  466.     address of the range in *start, the length of the
  467.     range in *length, and the offset of the first die
  468.     in the compilation-unit in *cu_die_offset.  It
  469.     returns false on error.
  470. */
  471. int
  472. dwarf_get_arange_info (
  473.     Dwarf_Arange    arange,
  474.     Dwarf_Addr        *start,
  475.     Dwarf_Unsigned    *length,
  476.     Dwarf_Off        *cu_die_offset,
  477.     Dwarf_Error        *error
  478. )
  479. {
  480.     if (arange == NULL) {
  481.     _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 
  482.     return(DW_DLV_ERROR);
  483.     }
  484.  
  485.     if (start != NULL) *start = arange->ar_address;
  486.     if (length != NULL) *length = arange->ar_length;
  487.     if (cu_die_offset != NULL)
  488.         *cu_die_offset = arange->ar_info_offset + 
  489.         arange->ar_dbg->de_length_size + CU_VERSION_STAMP_SIZE + 
  490.         arange->ar_dbg->de_length_size + CU_ADDRESS_SIZE_SIZE;
  491.  
  492.     return(DW_DLV_OK);
  493. }
  494.  
  495.